#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "view.h"
#include "cals.h"
#include "filesystem.h"
#include "about.h"
#include "parameter.h"

#include <QDebug>
#include <QChart>
#include <QPalette>
#include <QMessageBox>
#include <QProcess>
#include <QDesktopServices>
#include <QThread>
#include <QtConcurrent>
#include <QFuture>
#include <QFileDialog>
#include <QMutexLocker>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    initial_combox();

    can = new Can();
    pm_window = new Parameter();

    order_time = static_cast<unsigned long>(ui->comboBoxOrderGap->currentText().toDouble()*1000);
    wait_time = ui->comboBoxWaitTime->currentText().toInt()*1000;
    len = ui->comboBoxPixelCnt->currentText().toInt();

    connect(this,SIGNAL(can_wrong()),this,SLOT(deal_can_wrong()));

    //add style sheet
    QFile qss_file(":/origin.qss");
    qss_file.open(QFile::ReadOnly);
    this->setStyleSheet(qss_file.readAll());

    //set x data
    set_xPixels(ui->comboBoxPixelCnt->currentText());

    //start default theme
    connect(this,SIGNAL(change_theme(int)),pm_window,SLOT(update_ui(int)));
    on_actionInstrument_triggered();

    ui->progressBar->hide();
    ui->progressBar_2->hide();

    connect(this,SIGNAL(y_data_changed()),this,SLOT(deal_y_data_changed()));
    enable_con_sampe = false;
    continus_sample_save_cnts = 0;

    connect(this,SIGNAL(change_paras(const QString&,const QString&,const QString&,const QString&,const QString&)),
     pm_window,SLOT(deal_change_para(const QString&,const QString&,const QString&,const QString&,const QString&)));
    connect(this,SIGNAL(change_progress2_value(int)),this,SLOT(deal_change_progress2_value(int)));
    connect(this,SIGNAL(finish_continus_sample_save()),this,SLOT(deal_finish_continus_sample_save()));
}

MainWindow::~MainWindow()
{
    delete pm_window;
    delete ui;
}

//pushbutton
void MainWindow::on_pushButtonSingleSample_clicked()
{
    pm_window->set_para();

    bool can_finish = send_get_datas(can);
    if(!can_finish)
    {
        can_wrong();
        return;
    }

    deal_y_data_changed();
    save_file();
}

void MainWindow::on_pushButtonContinueSample_clicked()
{
    if(enable_con_sampe)
    {

        enable_con_sampe = false;

        ui->progressBar->setValue(0);
        ui->progressBar->hide();
        ui->pushButtonContinueSample->setText("开始连续采集");
    }
    else
    {
        enable_con_sampe = true;

        pm_window->set_para();
        future = QtConcurrent::run(this,&MainWindow::continus_sample,can);

        start_processbar();
        ui->pushButtonContinueSample->setText("正在连续采集");
    }
}

//void MainWindow::on_pushButtonOnlySend_clicked()
//{
//    pm_window->set_para();
//    only_send_data(can);
//    ui->statusBar->showMessage("指令已发送",1000);
//}

void MainWindow::on_pushButtonContinueSampleSave_clicked()
{
    if(continus_sample_save_cnts>0)
    {//stop sample
        continus_sample_save_cnts = 0;
        ui->pushButtonContinueSampleSave->setText("开始多次采集");
        return;
    }

    int cnts = ui->lineEditSampleCnts->text().toInt();
    if(cnts<=0){
        QMessageBox::critical(this,"错误","请输入正确的值");
        return;
    }

    continus_sample_save_cnts = cnts;
    y_data_multi_line.clear();

    ui->progressBar_2->setValue(0);
    ui->progressBar_2->setRange(0,cnts);
    ui->progressBar_2->show();

    ui->pushButtonContinueSampleSave->setText("正在多次采集");

    pm_window->set_para();

    QtConcurrent::run(this,&MainWindow::continus_sample_save,can);
}

void MainWindow::on_pushButtonResetAxes_clicked()
{
    ui->graphicsView->replot();
}

void MainWindow::on_pushButtonModifyConfirm_clicked()
{
    if(enable_con_sampe) on_pushButtonContinueSample_clicked();

    change_paras(ui->comboBoxFrameID->currentText(),ui->comboBoxBaud->currentText(),ui->comboBoxGain->currentText(),
                 ui->comboBoxInterTime->currentText(),ui->comboBoxWaitTime->currentText());

    order_time = static_cast<unsigned long>(ui->comboBoxOrderGap->currentText().toDouble()*1000);
    wait_time = ui->comboBoxWaitTime->currentText().toInt()*1000;
    len = ui->comboBoxPixelCnt->currentText().toInt();

    QMessageBox::information(this,"信息","参数修改完成");
}

//otrers.deal slot2
void MainWindow::continus_sample(Can* can){
    //time second, wait time
    bool can_finish;
    while(enable_con_sampe){
        QThread::msleep(order_time);
        QMutexLocker locker(&mutex);
        can_finish = send_get_datas(can);
        if(!can_finish)
        {
            can_wrong();
            break;
        }
        y_data_changed();
    }
}

void MainWindow::continus_sample_save(Can* can){
    //time second, wait time
    bool can_finish;
    int max = continus_sample_save_cnts+1;
    for(;continus_sample_save_cnts>0;--continus_sample_save_cnts)
    {
        QThread::msleep(order_time);
        QMutexLocker locker(&mutex);
        can_finish = send_get_datas(can);
        y_data_multi_line.append(y_data);

        if(!can_finish)
        {
            can_wrong();
            break;
        }
        y_data_changed();
        change_progress2_value(max - continus_sample_save_cnts);
    }
    finish_continus_sample_save();
}

void MainWindow::deal_change_progress2_value(int val)
{
    ui->progressBar_2->setValue(val);
}

void MainWindow::deal_finish_continus_sample_save()
{
    FileSystem *fs = new FileSystem();
    fs->save_file(x_pixels,y_data_multi_line,
                  ui->comboBoxGain->currentText(),ui->comboBoxInterTime->currentText(),
                  ui->comboBoxFrameID->currentText());
    ui->statusBar->showMessage("联合文件保存成功！",statusbar_time);
    delete fs;
    ui->pushButtonContinueSampleSave->setText("开始多次采集");
    ui->progressBar_2->setValue(0);
    ui->progressBar_2->hide();
}

bool MainWindow::send_get_datas(Can *can){
    QList<VCI_CAN_OBJ> outs;

    can->set_ids(pm_window->equ_id.toInt(),pm_window->dev_id.toInt());
    bool conn = can->connect();
    if(!conn) return false;

    bool cofig = can->set_config(pm_window->acc_code,pm_window->mask_code,
                                 pm_window->fil_type,pm_window->t0,pm_window->t1,pm_window->mode);
    if(!cofig) return  false;

    bool clear = can->clear_buffer();
    if(!clear) return false;

    bool send = can->send_data("0x"+pm_window->frame_id,pm_window->send_data);
    if(!send) return false;

    int len2 = len*2/8+surplus; //4 bit for num, 8 bit for frame, array include frame
    LONGLONG cnts = can->recieve_data(QString::number(len2),QString::number(wait_time),outs);
    if(cnts != (len*2/8+1)) return false;

    y_data = frame2voltage(outs);

    can->close();
    return true;
}

void MainWindow::save_file()
{
    FileSystem *fs = new FileSystem();
    fs->save_file(x_pixels,y_data,
                  ui->comboBoxGain->currentText(),ui->comboBoxInterTime->currentText(),
                  ui->comboBoxFrameID->currentText());

    ui->statusBar->showMessage("文件保存成功！",statusbar_time);
    delete fs;
}

void MainWindow::set_xPixels(const QString& pixel_cnts)
{
    x_pixels.clear();
    int cnts = pixel_cnts.toInt();
    for(int i=0;i<cnts;++i)
        x_pixels.append(i);
}


//bool MainWindow::only_send_data(Can *can){
//    can->set_ids(pm_window->equ_id.toInt(),pm_window->dev_id.toInt());
//    bool conn = can->connect();
//    bool config = can->set_config(pm_window->acc_code,pm_window->mask_code,
//                                 pm_window->fil_type,pm_window->t0,pm_window->t1,pm_window->mode);
//    bool clear = can->clear_buffer();
//    bool send = can->send_data("0x"+pm_window->frame_id,pm_window->send_data);
//    can->close();

//    if(conn&&config&&clear&&send)
//        return true;
//    return false;
//}

void MainWindow::deal_can_wrong()
{
    ui->progressBar->setValue(0);
    ui->progressBar->hide();
    QMessageBox::critical(this,"错误","未获取CAN数据");
    can->close();
}

void MainWindow::deal_y_data_changed()
{
    ui->graphicsView->plot(x_pixels,y_data);
}

void MainWindow::start_processbar()
{
    ui->progressBar->show();
    ui->progressBar->setRange(0,0);
    ui->progressBar->setFormat("自动采集中");
}

//others.ui
void MainWindow::update_ui(int i){
    QChart::ChartTheme theme = static_cast<QChart::ChartTheme>(i);
    QPalette pal = window()->palette();

    QFile qss_file;
    if (theme == QChart::ChartThemeDark) {
        qss_file.setFileName(":/dark.qss");
        pal.setColor(QPalette::Window, QRgb(0x121218));
        ui->graphicsView->setBackgroundBrush(QBrush(QColor(QRgb(0x121218))));
    } else if (theme == QChart::ChartThemeBlueCerulean) {
        qss_file.setFileName(":/dark.qss");
        pal.setColor(QPalette::Window, QRgb(0x40434a));
        ui->graphicsView->setBackgroundBrush(QBrush(QColor(QRgb(0x40434a))));
    } else if (theme == QChart::ChartThemeBrownSand) {
        qss_file.setFileName(":/origin.qss");
        pal.setColor(QPalette::Window, QRgb(0x9e8965));
        ui->graphicsView->setBackgroundBrush(QBrush(QColor(QRgb(0x9e8965))));
    } else if (theme == QChart::ChartThemeBlueNcs) {
        qss_file.setFileName(":/origin.qss");
        pal.setColor(QPalette::Window, QRgb(0xf0f0f0));
        ui->graphicsView->setBackgroundBrush(QBrush(QColor(QRgb(0xf0f0f0))));
    } else {
        qss_file.setFileName(":/origin.qss");
        pal.setColor(QPalette::Window, QRgb(0xf0f0f0));
        ui->graphicsView->setBackgroundBrush(QBrush(QColor(QRgb(0xf0f0f0))));
    }
    qss_file.open(QFile::ReadOnly);
    this->setStyleSheet(qss_file.readAll());
    window()->setPalette(pal);
}

void MainWindow::initial_combox(){
    ui->comboBoxFrameID->setCurrentText("0x11F");
    ui->comboBoxBaud->setCurrentText("500");
    ui->comboBoxPixelCnt->setCurrentText("512");
    ui->comboBoxGain->setCurrentText("*1");
    ui->comboBoxInterTime->setCurrentText("*1");
    ui->comboBoxWaitTime->setCurrentText("1");
    ui->comboBoxOrderGap->setCurrentText("0.001");
}

//menu action
void MainWindow::on_action_triggered()// open current path
{
    QUrl url = QUrl(QDir::currentPath());
    QDesktopServices::openUrl(url);
}

void MainWindow::on_action_2_triggered()//exit
{
    this->close();
}

void MainWindow::on_action_5_triggered()// show paramter dialog
{
    pm_window->show();
}

void MainWindow::on_action_3_triggered()//about
{
    About *about = new About(this);
    about->exec();
}

void MainWindow::on_actionx_triggered()
{//axis x change
    QList<double> x;
    QString fn = QFileDialog::getOpenFileName(this,"替代文件",QDir::currentPath(),"Text files (*.txt *.csv);");
    read_xaxis(fn,x);
    ui->graphicsView->plot(x,y_data);
}

// for change theme
void MainWindow::on_actionOrigin_triggered()
{//change theme
    ui->graphicsView->set_chart_theme(QChart::ChartThemeBlueNcs);
    update_ui(QChart::ChartThemeBlueNcs);
    change_theme(QChart::ChartThemeBlueNcs);
}

void MainWindow::on_actionLight_triggered()
{//change theme
    ui->graphicsView->set_chart_theme(QChart::ChartThemeBrownSand);
    update_ui(QChart::ChartThemeBrownSand);
    change_theme(QChart::ChartThemeBrownSand);
}

void MainWindow::on_actionInstrument_triggered()
{//change theme
    ui->graphicsView->set_chart_theme(QChart::ChartThemeBlueCerulean);
    update_ui(QChart::ChartThemeBlueCerulean);
    change_theme(QChart::ChartThemeBlueCerulean);
}

void MainWindow::on_actionDark_triggered()
{//change theme
    ui->graphicsView->set_chart_theme(QChart::ChartThemeDark);
    update_ui(QChart::ChartThemeDark);
    change_theme(QChart::ChartThemeDark);
}

void MainWindow::on_action_4_triggered()//design guide
{
    QString url_str = "https://gitee.com/ChinaYasuo/upper-compute/wikis/Home?sort_id=3378483";
    QUrl url(url_str);
    bool is_open = QDesktopServices::openUrl(url);
    if(!is_open)
        QMessageBox::critical(this,"错误","不能打开文档");
}

void MainWindow::on_action_6_triggered()//Start CANUSB-I II Tester Advanced
{
    QProcess *myProcess = new QProcess();
    myProcess->start("Tester.exe");
}

//events
void MainWindow::closeEvent(QCloseEvent *)
{
    pm_window->close();
}
//TODO: update version
void MainWindow::on_action_7_triggered()
{//check update version
//    QProcess *cmd = new QProcess(this);
//    cmd->write("check_update.bat");
    //read version
}

void MainWindow::on_action_8_triggered()
{//update

}
